#Quelques imports très utiles
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import seaborn as sns
from io import BytesIO
import base64
import warnings
import plotly.express as px
import json
from datetime import datetime
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import re
import folium
### II. Répartition de la population en France métropolitaine
### III. Répartition des véhicules électriques en France métropolitaine
### IV. Répartition des bornes électriques en France métropolitaine
URL = "https://www.insee.fr/fr/statistiques/fichier/2015759/deve-envir-emissions-co2.xlsx"
df = pd.read_excel(URL)
# Rendre le dataframe lisible
def transform(dataset):
colonnes = ['Émissions de gaz à effet de serre par activité'] + [ f'{i}' for i in range(1990,2023)]
dataset.set_axis(colonnes, axis=1, inplace=True)
dataset = dataset[3:11].reset_index()
dataset.drop('index', axis=1, inplace = True)
return dataset
df = transform(df)
df.head()
| Émissions de gaz à effet de serre par activité | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | ... | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Industrie de l’énergie | 78.851202 | 80.089495 | 81.357832 | 69.065977 | 65.973570 | 68.502396 | 72.081708 | 67.707550 | 80.069139 | ... | 60.838441 | 47.198489 | 49.956407 | 53.546045 | 57.306330 | 47.982937 | 46.237280 | 41.266444 | 42.490917 | 44.575656 |
| 1 | Industrie manufacturière et construction | 139.412357 | 151.891836 | 139.881424 | 134.659609 | 135.640506 | 136.156076 | 138.341342 | 137.138262 | 131.172430 | ... | 88.703973 | 86.003308 | 83.687003 | 83.202542 | 82.886590 | 82.798769 | 79.778832 | 72.046643 | 77.952643 | 72.973903 |
| 2 | Traitement centralisé des déchets | 15.770500 | 16.468496 | 17.264753 | 18.042975 | 18.419108 | 18.651170 | 18.695998 | 18.681612 | 19.112439 | ... | 16.672992 | 16.007408 | 14.990339 | 15.011350 | 15.092677 | 14.821750 | 16.019293 | 15.927553 | 15.208793 | 15.177475 |
| 3 | Usage des bâtiments et activités résidentiels/... | 93.260689 | 102.932198 | 99.120231 | 95.513850 | 89.059078 | 88.948882 | 98.907077 | 94.048578 | 98.784997 | ... | 98.034366 | 81.848655 | 84.846037 | 84.777680 | 84.062820 | 79.047162 | 76.038243 | 71.317465 | 75.090141 | 64.024935 |
| 4 | Agriculture/sylviculture | 88.297176 | 87.390855 | 87.067203 | 85.916454 | 85.034512 | 85.708999 | 86.605312 | 86.666545 | 86.890664 | ... | 81.963010 | 83.494725 | 83.110580 | 81.690808 | 81.314373 | 80.438064 | 78.615927 | 78.244410 | 76.506548 | 76.524915 |
5 rows × 34 columns
# Tracer l'évolution
plt.figure(figsize=(12,8))
sns.set(style="whitegrid")
palette = sns.color_palette("husl", n_colors=7)
colonnes = df.columns.to_list()[1:]
colonnes_int = [int(x) for x in colonnes]
for i in df.index.to_list():
if i<7:
nom = df['Émissions de gaz à effet de serre par activité'][i]
evol = [df[col][i] for col in colonnes]
#evol = df[colonnes][i:i+1].values
plt.plot(colonnes_int, evol, label = f'{nom}', color = palette[i])
else:
pass
plt.xlabel('Année')
plt.ylabel('en millions de tonnes d’équivalent CO₂')
plt.title('Évolution des émissions de gaz à effet de serre par activité')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show()
img_data = BytesIO() # Conversion du graphique en image base64
plt.savefig(img_data, format='png')
img_data.seek(0)
img_base64 = base64.b64encode(img_data.read()).decode()
graph_html = f'<img src="data:image/png;base64,{img_base64}" alt="Graphique d\'autonomie">' #conserver le graphique sous format html pour le site
<Figure size 640x480 with 0 Axes>
Lien vers le site : https://www.data.gouv.fr/fr/datasets/etude-facteurs-demissions-des-differents-modes-de-transport-routier/
Ce jeu de données est issu de la base de données européenne HBEFA v4.1 (Handbook of emissions factors for Road Transport) qui fournit des facteurs d’émissions, c’est-à-dire des émissions de polluants en g/km pour toutes les catégories de véhicules routiers (voiture particulière, véhicule utilitaire léger, véhicule lourd et deux-roues motorisé), chacune étant divisée en plusieurs sous-catégories, pour une grande variété de situations de trafic (type de voirie, vitesse limite et niveau de saturation du trafic associé). Les données extraites sont des facteurs d’émissions agrégés de CO, HC, NOx et particules par catégorie de véhicules (voiture, véhicule utilitaire léger, poids lourd, autocar, bus et deux roues motorisées), par carburant (essence, gazole et GNV uniquement pour les bus), pour des conditions de circulation moyennes (urbain, rural et mixte France) et pour chaque année allant de 2020 à 2030.
URL = 'https://www.data.gouv.fr/fr/datasets/r/3e00d056-13ef-4069-b7bb-045859750a90'
df = pd.read_csv(URL)
print(df['Véhicule'].unique())
print(df.columns.to_list())
['2RM' 'PL' 'Autocar' 'Bus' 'Voiture' 'VUL'] ['Année', 'Véhicule', 'Carburant', 'Roulage', 'CO (g/km)', 'HC (g/km)', 'NOx (g/km)', 'Particules (g/km)']
liste_vehicule = ['2RM', 'PL', 'Autocar', 'Bus', 'Voiture', 'VUL']
liste_df = [df[df['Véhicule']==f'{vehicule}'] for vehicule in liste_vehicule]
for i, dataframe in enumerate(liste_df):
palette = sns.color_palette("husl", n_colors=6)
dataframe_urbain = dataframe[dataframe['Roulage']=='Urbain']
dataframe_rural = dataframe[dataframe['Roulage']=='Rural']
plt.figure(figsize=(12,8))
plt.plot(dataframe_urbain['Année'], dataframe_urbain['CO (g/km)'], color = palette[0],
label = f"émissions de CO (g/km) pour les {liste_vehicule[i]} en zone urbaine")
plt.plot(dataframe_rural['Année'], dataframe_rural['CO (g/km)'], color = palette[1],
label = f"émissions de CO (g/km) pour les {liste_vehicule[i]} en zone rurale")
plt.plot(dataframe_urbain['Année'], dataframe_urbain['HC (g/km)'], color = palette[2],
label = f"émissions de HC (g/km) pour les {liste_vehicule[i]} en zone urbaine")
plt.plot(dataframe_rural['Année'], dataframe_rural['HC (g/km)'], color = palette[3],
label = f"émissions de HC (g/km) pour les {liste_vehicule[i]} en zone rurale")
plt.plot(dataframe_urbain['Année'], dataframe_urbain['NOx (g/km)'], color = palette[4],
label = f"émissions de NOx (g/km) pour les {liste_vehicule[i]} en zone urbaine")
plt.plot(dataframe_rural['Année'], dataframe_rural['NOx (g/km)'], color = palette[5],
label = f"émissions de NOx (g/km) pour les {liste_vehicule[i]} en zone rurale")
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.xlabel('Année')
plt.show()
#télécharger le fichier geojson
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
file = ur.urlopen("https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements-avec-outre-mer.geojson")
a = open ("DOWNLOAD/geojsonFRANCE.geojson", "w+")
for line in file :
a.write(str(line, encoding = "UTF-8"))
a.close()
#télécharger le fichier wikipedia
data = pd.read_html("https://fr.wikipedia.org/wiki/Liste_des_d%C3%A9partements_fran%C3%A7ais_class%C3%A9s_par_population_et_superficie")
file = data[0].to_csv("DOWNLOAD/PopDep.csv")
#On nettoie le dataframe pour le rendre lisible
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
def clean_dataframe() :
warnings.filterwarnings('ignore')
dataframe = pd.read_csv("DOWNLOAD/PopDep.csv", low_memory= False, delimiter = ",", encoding="UTF-8")
# Retirer les lignes du dataframe incompatible avec le fichier geojson
dataframe2 = dataframe.loc[dataframe["CodeInsee"].apply(lambda x : len(x)) < 3]
# Créer une colonne où chaque ligne représente un indice(float) de densité de population
dataframe2["Echelle de densité"]= dataframe2["Densité(hab./km2)"].apply(lambda x : np.log(float(x.replace(",",".").replace("\xa0",""))))
return dataframe2
#Affiche une carte de la France avec la densité de population par département
def create_choropleth_map():
#charge le fichier sous un format adéquat
geojsonf = json.load(open ("DOWNLOAD/geojsonFRANCE.geojson", "r"))
#crée une carte de la France coloriée par département par indice de densité
fig = px.choropleth(clean_dataframe(), locations = "CodeInsee", geojson = geojsonf, featureidkey= "properties.code", color = "Echelle de densité", hover_name="Département",hover_data=["Densité(hab./km2)"],title = 'Densité de population par département en France métropolitaine')
fig.update_geos(fitbounds = "locations", visible = False)
return fig
clean_dataframe()
create_choropleth_map()
Le fichier est trop volumineux pour pouvoir le stocker sur le github. C'est pourquoi nous opérons quelques modifications.
df = pd.read_csv('/Users/augustincablant/Desktop/data.csv')
df.head()
df.shape
# On ne conserve que la France
df_fr = df[df['Country']=='FR']
df_fr.shape
# On opère à une sélection des colonnes
colonnes_utiles = ['Mp','m (kg)', 'Ft', 'ep (KW)', 'z (Wh/km)','Status', 'year', 'Fuel consumption ', 'Electric range (km)']
df_fr = df_fr[colonnes_utiles]
print(df_fr.shape)
df_fr.to_csv('/Users/augustincablant/Documents/GitHub/Pycar/DOWNLOAD/voitures_fr.csv')
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
df = pd.read_csv('DOWNLOAD/voitures_fr.csv')
df.drop('Unnamed: 0', axis=1, inplace = True)
df.sample(10)
| Mp | m (kg) | Ft | ep (KW) | z (Wh/km) | Status | year | Fuel consumption | Electric range (km) | |
|---|---|---|---|---|---|---|---|---|---|
| 15608 | STELLANTIS | 1530.0 | ELECTRIC | 100.0 | 159.0 | P | 2022 | NaN | 351.0 |
| 197444 | RENAULT-NISSAN-MITSUBISHI | 1201.0 | ELECTRIC | 31.0 | 161.0 | P | 2022 | NaN | 188.0 |
| 182778 | RENAULT-NISSAN-MITSUBISHI | 1711.0 | ELECTRIC | 55.0 | 162.0 | P | 2022 | NaN | 435.0 |
| 207503 | RENAULT-NISSAN-MITSUBISHI | 1201.0 | ELECTRIC | 31.0 | 161.0 | P | 2022 | NaN | 187.0 |
| 137817 | TESLA-HONDA-JLR | 1835.0 | ELECTRIC | 88.0 | 144.0 | P | 2022 | NaN | 491.0 |
| 191624 | RENAULT-NISSAN-MITSUBISHI | 1577.0 | ELECTRIC | 51.0 | 173.0 | P | 2022 | NaN | 395.0 |
| 20326 | STELLANTIS | 1530.0 | ELECTRIC | 100.0 | 160.0 | P | 2022 | NaN | 350.0 |
| 20700 | STELLANTIS | 1623.0 | ELECTRIC | 100.0 | 159.0 | P | 2022 | NaN | 341.0 |
| 42524 | STELLANTIS | 1659.0 | ELECTRIC | 57.0 | 153.0 | P | 2022 | NaN | 353.0 |
| 105023 | RENAULT-NISSAN-MITSUBISHI | 1012.0 | ELECTRIC | 18.0 | 139.0 | P | 2022 | NaN | 230.0 |
list(df.columns)
['Mp', 'm (kg)', 'Ft', 'ep (KW)', 'z (Wh/km)', 'Status', 'year', 'Fuel consumption ', 'Electric range (km)']
list(df['Ft'].unique())
['ELECTRIC', 'PETROL/ELECTRIC', 'DIESEL/ELECTRIC', 'HYDROGEN']
list(df['Mp'].unique())
['RENAULT-NISSAN-MITSUBISHI', 'STELLANTIS', 'VOLKSWAGEN', 'TESLA-HONDA-JLR', nan, 'MAZDA-SUBARU-SUZUKI-TOYOTA', 'BMW', 'FORD', 'MERCEDES-BENZ', 'HYUNDAI MOTOR EUROPE', 'KIA']
# Autonomie des véhicules électriques en fonction de leur poids
plt.figure(figsize=(12,8))
sns.scatterplot(data=df, x='m (kg)', y = 'Electric range (km)', hue = 'Ft')
plt.xlabel('Poids en kg')
plt.ylabel('Autonomie en km')
plt.legend()
plt.title('Autonomie des véhicules électriques en fonction de leur poids')
plt.show()
# Autonomie des véhicules électriques en fonction de leur poids selon le constructeur
plt.figure(figsize=(12,8))
sns.scatterplot(data=df, x='m (kg)', y = 'Electric range (km)', hue = 'Mp')
plt.xlabel('Poids en kg')
plt.ylabel('Autonomie en km')
plt.title('Autonomie des véhicules électriques en fonction de leur poids selon le constructeur')
plt.legend()
plt.show()
plt.figure(figsize=(12,8))
sns.scatterplot(data=df, x='z (Wh/km)', y = 'Electric range (km)', hue = 'Mp')
plt.xlabel('Poids en kg')
plt.ylabel('Autonomie en km')
plt.legend()
plt.show()
# Comparons l'autonomie des véhicules
plt.figure(figsize=(12,8))
sns.histplot(data=df, x='Electric range (km)', bins = 200, label = 'Autonomie des véhicules électriques en France')
plt.legend()
plt.show()
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
data_vehicles_2013_2021 = pd.read_csv('DOWNLOAD/data_vehicles_french_2013_2021.csv', low_memory=False).fillna(0)
data_vehicles_2013_2021.head()
| ID | Country | VFN | Mp | Mh | Man | MMS | Tan | T | Va | ... | IT | Ernedc (g/km) | Erwltp (g/km) | De | Vf | Status | year | Date of registration | Fuel consumption | Electric range (km) | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 256235 | GR | 0 | POOL RENAULT | RENAULT | RENAULT SAS | RENAULT | e2*2001/116*0327*37 | R | BR1S | ... | 0 | 0.0 | 0.0 | 0.0 | 0.0 | F | 2013 | 0 | 0.0 | 0.0 |
| 1 | 256364 | GR | 0 | POOL RENAULT | RENAULT | RENAULT SAS | RENAULT | e2*2001/116*0327*54 | R | 2R40 | ... | 0 | 0.0 | 0.0 | 0.0 | 0.0 | F | 2013 | 0 | 0.0 | 0.0 |
| 2 | 256433 | GR | 0 | POOL RENAULT | RENAULT | RENAULT SAS | RENAULT | e2*2001/116*0359*29 | N | CNJ1 | ... | 0 | 0.0 | 0.0 | 0.0 | 0.0 | F | 2013 | 0 | 0.0 | 0.0 |
| 3 | 256451 | GR | 0 | POOL RENAULT | RENAULT | RENAULT SAS | RENAULT | e2*2001/116*0364*22 | W | KW25 | ... | 0 | 0.0 | 0.0 | 0.0 | 0.0 | F | 2013 | 0 | 0.0 | 0.0 |
| 4 | 256453 | GR | 0 | POOL RENAULT | RENAULT | RENAULT SAS | RENAULT | e2*2001/116*0373*25 | Z | BZ1V | ... | 0 | 0.0 | 0.0 | 0.0 | 0.0 | F | 2013 | 0 | 0.0 | 0.0 |
5 rows × 38 columns
repartitionvehiculesneufs = pd.read_excel('DOWNLOAD/sect-ind-auto-immat-energie.xlsx',header=3,)
repartitionvehiculesneufs = repartitionvehiculesneufs.loc[[0,1,2,3,4,5],:]
repartitionvehiculesneufs_2015_2021=repartitionvehiculesneufs[["Type d'énergie",2015,2021]]
repartitionvehiculesneufs_2015_2021.head()
| Type d'énergie | 2015 | 2021 | |
|---|---|---|---|
| 0 | Essence | 739.374 | 669.928 |
| 1 | Diesel | 1097.122 | 349.479 |
| 2 | Hybride1 | 61.617 | 430.899 |
| 3 | Électricité | 17.268 | 162.106 |
| 4 | Bicarburation (essence + GPL + GNV) | 1.553 | 46.422 |
#Répartition de vente des véhicules en fonction de leur motorisation
year=[2015,2021]
for i in year:
seuil_importance = 1
plt.figure(figsize=(8,8))
data=repartitionvehiculesneufs[["Type d'énergie",i]]
plt.pie( data.loc[:,i],
labels= data.loc[:,"Type d'énergie"],
autopct=lambda p: '{:.1f}%'.format(p) if p > seuil_importance else '',
startangle=90,
labeldistance=None)
val_legende=data.loc[:,i]/(sum(data.loc[:,i]))
plt.legend(bbox_to_anchor=(1.05, 1))
plt.title('Répartition de vente des véhicules en fonction de leur motorisation en {}'.format(i))
plt.show()
#on garde seulement les colonnes qui nous intéressent
data_vehicles_final=data_vehicles_2013_2021.loc[:,['Mh','Cn','year','Ft','m (kg)','Enedc (g/km)','Ewltp (g/km)','Electric range (km)','Fuel consumption ']].drop_duplicates(subset='Cn',keep='first').sort_values('year',ascending=True)
#on reshape les data (pour uniformiser les catégories)
data_vehicles_final = data_vehicles_final[data_vehicles_final['Mh']!='PSA']
data_vehicles_final = data_vehicles_final[data_vehicles_final['Ft']!=0]
data_vehicles_final['Ft']=data_vehicles_final['Ft'].apply(lambda x : x.lower())
data_vehicles_final.head(-10)
| Mh | Cn | year | Ft | m (kg) | Enedc (g/km) | Ewltp (g/km) | Electric range (km) | Fuel consumption | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | RENAULT | CLIO | 2013 | petrol | 1062.0 | 135.0 | 0.0 | 0.0 | 0.0 |
| 947 | AUTOMOBILES CITROEN | DS4 / 1.6 / HDI AUT. | 2013 | diesel | 1375.0 | 114.0 | 0.0 | 0.0 | 0.0 |
| 946 | AUTOMOBILES CITROEN | DS4 / 1.6 / HDI | 2013 | diesel | 1370.0 | 113.0 | 0.0 | 0.0 | 0.0 |
| 945 | AUTOMOBILES CITROEN | DS3 RACING / 1.6 / 16V TURBO | 2013 | petrol | 1240.0 | 149.0 | 0.0 | 0.0 | 0.0 |
| 944 | AUTOMOBILES CITROEN | DS3 / 1.6 / 16V TURBO | 2013 | petrol | 1165.0 | 135.0 | 0.0 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1593 | AUTOMOBILES CITROEN | JUMPY SPACE TOURER / 2.0 / HDI L2 | 2021 | diesel | 1793.0 | 0.0 | 183.0 | 0.0 | 7.0 |
| 1592 | AUTOMOBILES CITROEN | JUMPY SPACE TOURER / 2.0 / AUT.HDI L2 | 2021 | diesel | 1839.0 | 0.0 | 186.0 | 0.0 | 7.1 |
| 1591 | AUTOMOBILES CITROEN | JUMPY SPACE TOURER / 1.5 / HDI L2 | 2021 | diesel | 1734.0 | 0.0 | 167.0 | 0.0 | 6.4 |
| 1584 | AUTOMOBILES CITROEN | C4 SPACETOURER / 2.0 / HDI AUT. | 2021 | diesel | 1615.0 | 0.0 | 160.0 | 0.0 | 6.1 |
| 1598 | AUTOMOBILES PEUGEOT | EXPERT TRAVELLER / 2.0 / AUT. HDI L3 | 2021 | diesel | 1842.0 | 0.0 | 186.0 | 0.0 | 7.1 |
1662 rows × 9 columns
data_vehicles_constr = data_vehicles_final.loc[:,['Mh','year','Enedc (g/km)', 'Ewltp (g/km)']].groupby(['year','Mh'])
data_emission_mean = data_vehicles_constr.mean() #on construit le dataframe de la valeur moyenne des émissions
constr=list(set(data_vehicles_final['Mh'])) #on récupère la liste des constructeurs
year=[2013,2021]
for i in range(len(year)):
data_emission=data_emission_mean.loc[data_emission_mean.index[[3*i,3*i+1,3*i+2]]]
if i==0:
values='Enedc (g/km)' #type de controle qui a changé
elif i==1:
values = 'Ewltp (g/km)' #type de controle qui a changé
plt.figure(figsize=(12,8))
plt.bar(constr, data_emission[values])
plt.legend(bbox_to_anchor=(1.05, 1))
plt.show()
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
#affichage de la répartition des véhicules neufs dévéloppés par les constructeurs français
year=[2013,2021]
for i in range(len(year)):
data=data_vehicles_final[data_vehicles_final["year"]==year[i]]
compt_ft=data['Ft'].value_counts()
plt.figure(figsize=(8,8))
plt.pie(compt_ft.values,
labels=compt_ft.index,
autopct=lambda p: '{:.1f}%'.format(p) if p > seuil_importance else '',
startangle=90,
labeldistance=None)
plt.legend(bbox_to_anchor=(1.05, 1))
plt.title('Répartition des véhicules neufs en fonction de leur motorisation en {}'.format(year[i]))
plt.show()
# classement des voitures électriques en 2023
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
classement = pd.read_csv('SCRAP/classement_VE_2023.csv')
classement.sort_values(by = 'Classement', inplace = True)
plt.figure(figsize = (16,8))
sns.barplot(x='Voitures', y='Classement', data=classement, palette='viridis')
plt.title('Classement des voitures électriques en 2023')
plt.xlabel('Voitures')
plt.ylabel('Classement')
plt.xticks(rotation=90)
plt.legend()
plt.show()
# classement.head()
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
# Faire apparaître le top 10
plt.figure(figsize=(12, 4))
sns.barplot(x='Voitures', y='Classement', data=classement[0:10], palette='viridis')
plt.title('Classement des 10 premières voitures électriques en 2023')
plt.xlabel('Classement')
plt.ylabel('Voitures')
plt.xticks(rotation = 90)
plt.show()
autonomie = pd.read_csv('SCRAP/autonomie_VE.csv')
autonomie.drop_duplicates(subset = 'Voitures', inplace = True)
autonomie.head()
| Classement | Voitures | kWh | Prix | Autonomie | |
|---|---|---|---|---|---|
| 0 | 1.0 | Mercedes EQS | 108.0 | 135 850 € | 783 km |
| 1 | 2.0 | Fisker Ocean | 106.0 | 69 950 € | 707 km |
| 3 | 4.0 | Volkswagen ID.7 | 86.0 | NaN | 700 km |
| 4 | 4.0 | Peugeot e-3008 | 98.0 | NaN | 700 km |
| 6 | 7.0 | Tesla Model 3 | 76.0 | 50 990 € | 678 km |
def get_km(row):
if not pd.isna(row):
return int(row.split(' ')[0])
else:
return row
autonomie['Autonomie_int'] = autonomie['Autonomie'].apply(get_km)
autonomie.sort_values(by = 'Autonomie_int', ascending = False, inplace = True)
plt.figure(figsize=(16, 8))
sns.barplot(x='Voitures', y='Autonomie_int', data=autonomie[0:10], palette='viridis')
plt.title('Classement des 10 premières voitures électriques les plus autonomes en 2023')
plt.xlabel('Voitures')
plt.ylabel('Autonomie en km')
plt.xticks(rotation = 90)
plt.show()
os.chdir("/Users/augustincablant/Documents/GitHub/PyCar")
def evolution_nbre_voiture_elec():
df = pd.read_csv('DOWNLOAD/Voitures.csv', sep=';')
List_date = []
List_nombre = []
for row in df.itertuples():
date0 = row.date_arrete
date = datetime.strptime(date0, "%d/%m/%Y").strftime("%Y-%m-%d")
nbre = row.nb_vp_rechargeables_el
if date in List_date:
for i in range(len(List_date)):
if List_date[i] == date:
List_nombre[i] += nbre
else:
List_date.append(date)
List_nombre.append(nbre)
dict = {'Date': List_date, 'Nombre': List_nombre}
dataframe = pd.DataFrame(dict)
df0 = dataframe.sort_values('Date')
fig = px.line(df0, x='Date', y='Nombre',
title='Evolution du parc de véhicules électriques en France')
return fig
evolution_nbre_voiture_elec()
Ce jeu de données permet de visualiser l’évolution trimestrielle (à partir de de T4 2020) du stock de voitures immatriculées dans chaque commune de France métropolitaine et DOM.
URL = 'https://www.data.gouv.fr/fr/datasets/r/4e4fccdb-6acb-4e31-8b2d-cb170f639f1a'
df = pd.read_csv(URL, sep = ';')
print(df.shape)
print(list(df.columns))
(422164, 8) ['codgeo', 'libgeo', 'epci', 'libepci', 'date_arrete', 'nb_vp_rechargeables_el', 'nb_vp_rechargeables_gaz', 'nb_vp']
df.sample(5)
| codgeo | libgeo | epci | libepci | date_arrete | nb_vp_rechargeables_el | nb_vp_rechargeables_gaz | nb_vp | |
|---|---|---|---|---|---|---|---|---|
| 395142 | 65406 | SARNIGUET | 200069300.0 | CA Tarbes-Lourdes-Pyrénées | 2021-03-31 | 2 | 0 | 318 |
| 328867 | 53011 | ASTILLÉ | 200048551 | CC du Pays de Craon | 2020-12-31 | 5 | 0 | 808 |
| 330436 | 54173 | DROUVILLE | 245400759 | CC du Pays du Sanon | 2021-09-30 | 0 | 0 | 182 |
| 272824 | 77380 | PUISIEUX | 247700065 | CC du Pays de l'Ourcq | 2021-03-31 | 4 | 0 | 397 |
| 93121 | 12095 | ESCANDOLIÈRES | 241200625 | CC du Pays Rignacois | 2023-06-30 | 5 | 0 | 259 |
# Récupérer les départements
def create_departement(dataframe):
dataframe['Dep'] = dataframe['codgeo'].str.slice(0, 2)
return dataframe
df = create_departement(df)
df.groupby("Dep")["nb_vp_rechargeables_el"].sum().reset_index()
| Dep | nb_vp_rechargeables_el | |
|---|---|---|
| 0 | 01 | 35994 |
| 1 | 02 | 53269 |
| 2 | 03 | 34011 |
| 3 | 04 | 24126 |
| 4 | 05 | 18994 |
| ... | ... | ... |
| 75 | 92 | 160815 |
| 76 | 93 | 60607 |
| 77 | 94 | 61384 |
| 78 | 95 | 53672 |
| 79 | 97 | 54954 |
80 rows × 2 columns
def new_dataframeS(dataframe):
colonnes = ['Dep', 'nb_vp_rechargeables_el','nb_vp']
dataframe = dataframe[colonnes]
dataframe_elec = dataframe.groupby("Dep")["nb_vp_rechargeables_el"].sum().reset_index()
dataframe_total = dataframe.groupby("Dep")["nb_vp"].sum().reset_index()
return dataframe_elec, dataframe_total
df_elec, df_total = new_dataframeS(df)
#Affiche une carte de la France avec le nombre de voitures par département
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
def create_choropleth_map(dataframe, titre, colonne):
#charge le fichier sous un format adéquat
geojsonf = json.load(open ("DOWNLOAD/geojsonFRANCE.geojson", "r"))
#crée une carte de la France coloriée par département par indice de densité
fig = px.choropleth(dataframe, locations = "Dep", geojson = geojsonf, featureidkey= "properties.code", color = colonne,
hover_data= [colonne], title = titre)
fig.update_geos(fitbounds = "locations", visible = True)
return fig
create_choropleth_map(df_elec, "Nombre de voitures électriques par département en France Métropolitaine", 'nb_vp_rechargeables_el')
create_choropleth_map(df_total, "Nombre de voitures par département en France Métropolitaine", 'nb_vp')
Source : https://www.iea.org/data-and-statistics/data-tools/global-ev-data-explorer
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
df = pd.read_csv('DOWNLOAD/IEA-EV-dataEV salesProjection-STEPSCars.csv')
df.head()
| region | category | parameter | mode | powertrain | year | unit | value | |
|---|---|---|---|---|---|---|---|---|
| 0 | China | Projection-STEPS | Oil displacement Mbd | Cars | EV | 2020 | Milion barrels per day | 0.046 |
| 1 | China | Projection-STEPS | Oil displacement, million lge | Cars | EV | 2020 | Oil displacement, million lge | 2800.000 |
| 2 | China | Projection-STEPS | EV stock share | Cars | EV | 2020 | percent | 1.800 |
| 3 | China | Projection-STEPS | Electricity demand | Cars | EV | 2020 | GWh | 13000.000 |
| 4 | China | Projection-STEPS | EV sales share | Cars | EV | 2020 | percent | 5.800 |
for region in list(df['region'].unique()):
years = [2020, 2021, 2022, 2025, 2030]
colors = plt.cm.viridis(np.linspace(0, 1, len(years)))
IEA = "Agence Internationale de l'Energie"
sub_df1 = df[df['region'] == region]
sub_df = sub_df1[sub_df1['parameter'] == 'EV sales']
years = sub_df['year'].to_list()
values = sub_df['value'].to_list()
plt.figure(figsize=(12,8))
plt.bar(years, values, color = colors)
plt.title(f"Prévision de ventes de véhicules électriques dans la région {region} selon l'{IEA}")
plt.grid(True)
plt.xlabel('Années')
plt.ylabel("Nombre de véhicules électriques (en millions)")
plt.show()
Objectif : prédire le nombre de bornes de recharges dans le futur
URL_DATASET = 'https://data.enedis.fr/api/explore/v2.1/catalog/datasets/nombre-total-de-points-de-charge/exports/csv?lang=fr&timezone=Europe%2FBerlin&use_labels=true&delimiter=%3B'
df = pd.read_csv(URL_DATASET, sep = ';')
df.sample(5)
| Trimestre | Ouvert au public | Particulier | Société | |
|---|---|---|---|---|
| 8 | 2018 T3 | 24319 | 97164 | 96616 |
| 33 | 2017 T2 | 19750 | 68509 | 68930 |
| 6 | 2020 T2 | 32648 | 192823 | 180499 |
| 14 | 2016 T2 | 13861 | 48412 | 52015 |
| 20 | 2015 T1 | 8478 | 25638 | 34746 |
df.shape
(35, 4)
def transform_col1(row):
year = row.split(' ')[0]
return year
def transform_col2(row):
sem = row.split('T')[1]
return sem
df['Semestre'] = df['Trimestre'].apply(transform_col2)
df['Année'] = df['Trimestre'].apply(transform_col1)
def transform_col3(row):
row = row.split('T')
year = row[0]
sem_nb = row[1]
return year + 'Q' + sem_nb
df['Trimestre'] = df['Trimestre'].apply(transform_col3)
df['Trimestre'] = pd.to_datetime(df['Trimestre'], format='%Y Q%m')
df.head()
| Trimestre | Ouvert au public | Particulier | Société | Semestre | Année | |
|---|---|---|---|---|---|---|
| 0 | 2023-03-01 | 109856 | 906942 | 652131 | 3 | 2023 |
| 1 | 2022-03-01 | 71630 | 623836 | 446585 | 3 | 2022 |
| 2 | 2020-01-01 | 31081 | 172822 | 167797 | 1 | 2020 |
| 3 | 2016-04-01 | 16220 | 57039 | 59408 | 4 | 2016 |
| 4 | 2020-04-01 | 34686 | 267371 | 237863 | 4 | 2020 |
list(df.columns)
['Trimestre', 'Ouvert au public', 'Particulier', 'Société', 'Semestre', 'Année']
df.sort_values(by = ['Année', 'Semestre'], inplace = True)
df.head()
| Trimestre | Ouvert au public | Particulier | Société | Semestre | Année | |
|---|---|---|---|---|---|---|
| 20 | 2015-01-01 | 8478 | 25638 | 34746 | 1 | 2015 |
| 10 | 2015-02-01 | 10086 | 29662 | 37933 | 2 | 2015 |
| 34 | 2015-03-01 | 10928 | 32278 | 38681 | 3 | 2015 |
| 9 | 2015-04-01 | 11113 | 37448 | 42891 | 4 | 2015 |
| 26 | 2016-01-01 | 12830 | 43284 | 48013 | 1 | 2016 |
def total(dataframe):
dataframe['Total'] = dataframe['Ouvert au public'] + dataframe['Particulier'] + dataframe['Société']
return dataframe
df = total(df)
df.head()
| Trimestre | Ouvert au public | Particulier | Société | Semestre | Année | Total | |
|---|---|---|---|---|---|---|---|
| 20 | 2015-01-01 | 8478 | 25638 | 34746 | 1 | 2015 | 68862 |
| 10 | 2015-02-01 | 10086 | 29662 | 37933 | 2 | 2015 | 77681 |
| 34 | 2015-03-01 | 10928 | 32278 | 38681 | 3 | 2015 | 81887 |
| 9 | 2015-04-01 | 11113 | 37448 | 42891 | 4 | 2015 | 91452 |
| 26 | 2016-01-01 | 12830 | 43284 | 48013 | 1 | 2016 | 104127 |
for col in ['Ouvert au public', 'Particulier', 'Société', 'Total']:
plt.figure(figsize = (12,8))
plt.plot(df['Trimestre'], df[col])
plt.xlabel('Trimestre')
plt.xticks(rotation=90)
plt.ylabel('Nombre de bornes')
plt.title(f'Évolution du nombre de recharges {col} en France')
plt.show()
Nous avons très peu d'informations et possédons seulement des périodes. C'est pourquoi nous choisissons une simple régression linéaire.
Nous nous accordons à dire qu'avec si peu de features, les prédictions du modèle sont vraiment à prendre avec des pincettes. Toutefois, nous voulions quand même nous essayer à la prédiction dans ce projet.
X = df[['Semestre', 'Année']]
y = df['Total']
# Diviser les données en ensembles d'entraînement et de test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, shuffle=False)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test) #prédictions sur l'ensemble de test
# Évaluer les performances du modèle
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# Afficher les résultats
print(f'Mean Squared Error: {mse}')
print(f'R-squared: {r2}')
Mean Squared Error: 416459288139.51404 R-squared: -2.8520673877147535
plt.figure(figsize=(12,8))
date_train = [year + ' Q' + sem for sem, year in X_train[['Semestre', 'Année']].values]
date_test = [year + ' Q' + sem for sem, year in X_test[['Semestre', 'Année']].values]
plt.plot(pd.to_datetime(date_train, format='%Y Q%m'), y_train, color = 'blue', label = 'Train')
plt.plot(pd.to_datetime(date_test, format='%Y Q%m'), y_test, color = 'cyan', label = 'Test')
plt.plot(pd.to_datetime(date_test, format='%Y Q%m'), y_pred, color = 'orange', label = 'Predictions')
plt.legend()
plt.xlabel('Temps')
plt.ylabel('Nombre de bornes')
plt.show()
# on mélange les dates d'entraînement en enlevant shuffle = False
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test) #prédictions sur l'ensemble de test
# Évaluer les performances du modèle
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# Afficher les résultats
print(f'Mean Squared Error: {mse}')
print(f'R-squared: {r2}')
Mean Squared Error: 42673224090.80993 R-squared: 0.4712165057853327
X_pred = pd.DataFrame([['4', '2023'], ['1', '2024'], ['2', '2024'], ['3', '2024'], ['4', '2024'],
['1', '2025'], ['2', '2025'], ['3', '2025'], ['4', '2025'],
['1', '2026'], ['2', '2026'], ['3', '2026'], ['4', '2026']], columns = ['Semestre', 'Année'])
date_predictions = [year + ' Q' + sem for sem, year in X_pred[['Semestre', 'Année']].values]
predictions = model.predict(X_pred)
plt.figure(figsize=(12,8))
date = [year + ' Q' + sem for sem, year in X[['Semestre', 'Année']].values]
plt.plot(pd.to_datetime(date, format='%Y Q%m'), y, color = 'blue', label = 'Connues')
plt.plot(pd.to_datetime(date_predictions, format='%Y Q%m'), predictions, color = 'orange', label = 'Predictions')
plt.legend()
plt.xlabel('Temps')
plt.ylabel('Nombre de bornes')
plt.show()
Visualisons les bornes de recharge pour les véhicules électriques en France
Le jeu de données que nous allons utiliser date du 23 juillet 2023, vous pouvez le retrouver sur cette page.
# On commence par récupérer notre data set
URL = 'https://www.data.gouv.fr/fr/datasets/r/517258d5-aee7-4fa4-ac02-bd83ede23d25'
df = pd.read_csv(URL, sep = ';')
df.sample(5)
| n_amenageur | n_operateur | n_enseigne | id_station | n_station | ad_station | code_insee | xlongitude | ylatitude | nbre_pdc | ... | type_prise | acces_recharge | accessibilite | observations | date_maj | source | geo_point_borne | code_insee_commune | region | departement | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3142 | Opel Lievin | DRIVECO | Opel Lievin | FR*G44*PLEMPEREUROPEL62800*1 | Opel Lievin | Forum de l'Automobile Avenue François Mitteran... | 62510.0 | 2.786037 | 50.426319 | 6.0 | ... | EF, T2 | Gratuit | 24/24 7/7 jours | NaN | 2021-03-03 | https://www.data.gouv.fr/fr/datasets/liste-des... | 50.426319,2.786037 | 62510 | Hauts-de-France | Pas-de-Calais |
| 7007 | Mairie de Paris | Mairie de Paris | Paris Recharge | FR*W75*PVP*0002 | 2 RUE DE L'AMIRAL DE COLIGNY | 2 RUE DE L'AMIRAL DE COLIGNY, 75001 PARIS | 75101.0 | 2.340240 | 48.859710 | 6.0 | ... | prise T3 | payant | 7/7-24/24 | Courant: AC mono|tarif: 120€/an|https://www.pa... | 2020-07-22 | https://www.data.gouv.fr/fr/datasets/paris-rec... | 48.85971,2.34024 | 75056 | Île-de-France | Paris |
| 9186 | TOTAL MARKETING FRANCE | TOTAL MARKETING FRANCE | Belib' | FR*V75*PPX08*03 | Paris | Rue d'Astorg 11 | 66 Rue d'Astorg, 75008 Paris | 75108.0 | 2.319389 | 48.872833 | 6.0 | ... | T2-EF | payant | 7/7-24/24 | https://belib.paris | 2021-05-04 | https://www.data.gouv.fr/fr/datasets/belib-poi... | 48.872833,2.3193886 | 75056 | Île-de-France | Paris |
| 16501 | Communauté d'Agglomération Maubeuge Val de Sambre | BOUYGUES ENERGIES ET SERVICES | pass pass électrique | FR*H02*P59187*001 | ECLAIBES - Ch Margot | Ch Margot 59330 ÉCLAIBES | 59187.0 | 3.932986 | 50.202984 | 2.0 | ... | EF - T2 | payant | 24h/24 7j/7 | Recharge par badge et avec une application sma... | 2020-04-03 | https://www.data.gouv.fr/fr/datasets/infrastru... | 50.202984,3.932986 | 59187 | Hauts-de-France | Nord |
| 10253 | Syndicat Départemental d'Énergie de Loire-Atla... | Syndicat Départemental d'Énergie de Loire-Atla... | SYDEGO | FR*S44*P44130C | Pont-Saint-Martin | Rue de la Flamme Olympique | Rue de la Flamme Olympique 44860 Pont-Saint-Ma... | NaN | -1.540393 | 47.112585 | 1.0 | ... | CHAdeMO-Combo-T2 câble attaché | Payant | 24/24 7/7 | NaN | 2020-07-10 | https://www.data.gouv.fr/fr/datasets/bornes-de... | 47.112585,-1.540393 | 44130 | Pays de la Loire | Loire-Atlantique |
5 rows × 22 columns
Catégories d'accès à la borne :
Comme l'illustre la cellule de code suivante, les catégories proposées ne sont pas très propres. Remédions à cela.
list(df['acces_recharge'].unique())
['gratuit', 'payant', 'Payant', 'Carte Mobive', nan, 'Gratuit', 'GRATUIT', 'gratuit pour la clientèle du parking', '0.19€/kWh + 0.01€/min', 'QR code / appli mobile / Carte RFID', 'badge RFID; QR Code', 'Payant (badge, appli et QR code)', 'Public payant', 'Accès payant (Badge RFID, application, site web paynow.sodetrel.fr, badges vendus en boutique)', 'Charges gratuites de 12 à 14h et de 19h à 21h', 'oui', '5€ / 45min, si abonné (10€/mois) : 1€/10min', 'Réservation préalable, accès par badge', '2€/recharge', '2€/recharge+ prix du stationnement']
def transform_acces(row):
if not pd.isna(row): # On ne peut rien dire des nan
row = row.lower() # Mettre en lettre minuscule
mots = row.split(' ')
if 'payant' in mots: row = 'payant'
elif 'gratuit' in mots: row = 'gratuit'
for mot in mots:
if len(mot.split('€'))>1: row = 'payant'
if mot=='carte' or mot=='badge': row = 'carte ou badge'
if mot=='oui': row = 'information manquante'
#else: row = 'accès spécial'
else: row = 'information manquante'
return row
df['acces_recharge'] = df['acces_recharge'].apply(transform_acces)
list(df['acces_recharge'].unique())
['gratuit', 'payant', 'carte ou badge', 'information manquante', 'charges gratuites de 12 à 14h et de 19h à 21h']
On veut ensuite s'assurer que nous disposons de toutes les informations concernant les coordonénes géographiques des bornes de recharge ...
print('Il y a ', df[df['xlongitude'].isna()].shape[0], 'valeurs manquantes pour xlongitude')
print('Il y a ', df[df['ylatitude'].isna()].shape[0], 'valeurs manquantes pour ylatitude')
sns.heatmap(df[['xlongitude', 'ylatitude']].isna(), cmap = 'magma', cbar = False)
Il y a 30 valeurs manquantes pour xlongitude Il y a 6 valeurs manquantes pour ylatitude
<Axes: >
droping_liste = list(set(df[df['xlongitude'].isna()].index.to_list() + df[df['ylatitude'].isna()].index.to_list()))
df.drop(droping_liste, inplace = True)
Regardons plus attentivement la répartition des bornes en France
bornes_region = df['region'].value_counts().reset_index() # On compte le nombre de bornes par région
bornes_region.columns = ['region', 'nombre de bornes']
bornes_region = bornes_region.sort_values(by='nombre de bornes', ascending=False)
# On affiche cela dans un histogramme
plt.figure(figsize=(12, 6))
plt.bar(bornes_region['region'], bornes_region['nombre de bornes'])
plt.xlabel('Région')
plt.ylabel('Nombre de bornes')
plt.title('Nombre de bornes de recharge pour les véhicules électriques par région')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()
# Quelques modifications pour le futur merge
bornes_region['region'][11] = 'Grand Est'
bornes_region['region'][9] = 'Île-de-France'
bornes_region['region'][8] = 'Centre-Val-de-Loire'
On peut se demander si le nombre de bornes est proportionnel au nombre de voitures électriques présentes dans ces régions.
i) Commençons par regarder l'évolution du nombre de véhicules électrique en France depuis 2010
ii) Puis regardons la répartition des nouveaux véhicules électriques en France en 2018
# Commençons par regarder l'évolution du nombre de véhicules électrique
# Pour cela nous avons scrappé les données de wikipedia, le contenu se trouve dans le dossier SCRAP : 'scrap_VE.py'
os.chdir("/Users/augustincablant/Documents/GitHub/Pycar")
EVOL_VE = pd.read_csv('SCRAP/EVOL_VE.csv')
fig, ax1 = plt.subplots()
ax1.plot(EVOL_VE['Année'], EVOL_VE['Part de marché'], color='red', alpha=0.8, label='Part de marché des véhicules électrique')
ax1.set_xlabel('Années')
ax1.set_ylabel('Parts de marché')
ax1.set_xlim(2010, 2023)
ax2 = ax1.twinx()
ax2.scatter(EVOL_VE['Année'], EVOL_VE['Voitures particulières'], color='blue', label='Voitures particulières')
ax2.scatter(EVOL_VE['Année'], EVOL_VE['Utilitaires'], color='orange', label='Utilitaires')
ax2.set_ylabel('Nombre de voitures')
ax1.legend()
ax2.legend(loc = 'center left')
plt.show()
# Répartition des nouveaux véhicules électriques en France en 2018
VE_REP = pd.read_csv('SCRAP/VE_2018.csv')
VE_REP.sort_values(by = 'Immatriculations', ascending = False, inplace=True)
plt.figure(figsize=(12, 6))
plt.bar(VE_REP['Département'], VE_REP['Immatriculations'], color = 'grey')
plt.xlabel('Département')
plt.ylabel('Nombre de nouvelles immatriculations')
plt.title('Nombre de nouvelles immatriculations par région en France en 2018')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()
VE_REP = pd.read_csv('SCRAP/VE_2018.csv')
def get_number(row):
return float('.'.join(re.findall(r'\d+', row)))
VE_REP['parts'] = VE_REP['Part de marché'].apply(get_number)
VE_REP.sort_values(by = 'parts', inplace=True, ascending = False)
plt.figure(figsize=(12, 6))
plt.bar(VE_REP['Département'], VE_REP['parts'], color = 'orange')
plt.xlabel('Département')
plt.ylabel("Part de marché de l'électrique en %")
plt.title('Part de marché des voitures électriques par région en France en 2018')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()
Que peut-on dire des villes ?
code_insee = pd.read_csv('https://www.insee.fr/fr/statistiques/fichier/6800675/v_commune_2023.csv')
code_insee.head()
| TYPECOM | COM | REG | DEP | CTCD | ARR | TNCC | NCC | NCCENR | LIBELLE | CAN | COMPARENT | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | COM | 01001 | 84.0 | 01 | 01D | 012 | 5 | ABERGEMENT CLEMENCIAT | Abergement-Clémenciat | L'Abergement-Clémenciat | 0108 | NaN |
| 1 | COM | 01002 | 84.0 | 01 | 01D | 011 | 5 | ABERGEMENT DE VAREY | Abergement-de-Varey | L'Abergement-de-Varey | 0101 | NaN |
| 2 | COM | 01004 | 84.0 | 01 | 01D | 011 | 1 | AMBERIEU EN BUGEY | Ambérieu-en-Bugey | Ambérieu-en-Bugey | 0101 | NaN |
| 3 | COM | 01005 | 84.0 | 01 | 01D | 012 | 1 | AMBERIEUX EN DOMBES | Ambérieux-en-Dombes | Ambérieux-en-Dombes | 0122 | NaN |
| 4 | COM | 01006 | 84.0 | 01 | 01D | 011 | 1 | AMBLEON | Ambléon | Ambléon | 0104 | NaN |
merge_df = pd.merge(df, code_insee, left_on='code_insee_commune', right_on='COM')
merge_df.sample()
| n_amenageur | n_operateur | n_enseigne | id_station | n_station | ad_station | code_insee | xlongitude | ylatitude | nbre_pdc | ... | REG | DEP | CTCD | ARR | TNCC | NCC | NCCENR | LIBELLE | CAN | COMPARENT | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 729 | SDEE48 48 | BOUYGUES ENERGIES ET SERVICES | Révéo | FR*S48*P48088*001 | LA MALENE - Parking Du Tarn | Parking Du Tarn 48210 LA MALENE | 48088.0 | 3.320673 | 44.300836 | 2.0 | ... | 76.0 | 48 | 48D | 481 | 3 | MALENE | Malène | La Malène | 4802 | NaN |
1 rows × 34 columns
merge_df.columns
Index(['n_amenageur', 'n_operateur', 'n_enseigne', 'id_station', 'n_station',
'ad_station', 'code_insee', 'xlongitude', 'ylatitude', 'nbre_pdc',
'id_pdc', 'puiss_max', 'type_prise', 'acces_recharge', 'accessibilite',
'observations', 'date_maj', 'source', 'geo_point_borne',
'code_insee_commune', 'region', 'departement', 'TYPECOM', 'COM', 'REG',
'DEP', 'CTCD', 'ARR', 'TNCC', 'NCC', 'NCCENR', 'LIBELLE', 'CAN',
'COMPARENT'],
dtype='object')
#Il faut choisir l'échelle parmi les éléements de liste_echelle pour les fonctions suivantes
liste_echelle = ['LIBELLE','departement','region']
def top20_bornes(dataframe, echelle):
"""
Renvoie un dataframe contenant les 20 plus grandes localisations selon l'échelle ayant le plus de bornes
"""
df_villes = dataframe[echelle].value_counts()
df_top20 = df_villes.head(20)
return df_top20
def afficher_top20(echelle):
"""
Affiche un bar chart en fonction de l'échelle donnée en argument
"""
df = top20_bornes(merge_df,echelle)
fig = px.bar(df)
fig.update_layout(title_text="Les 20 {}s ayant le plus d'infrastructuress de recharge".format(echelle.lower()))
fig.update_yaxes(title_text='Nombre de bornes')
fig.update_xaxes(title_text='{}s'.format(echelle))
return fig
afficher_top20(liste_echelle[0])
afficher_top20(liste_echelle[1])
afficher_top20(liste_echelle[2])
On peut désormais passer à la visualisation de ces bornes !
# Récupérer les données pour afficher la carte du monde
map_osm = folium.Map(location=[48.85, 2.34])
legend_html = """
<div style="position: fixed;
bottom: 100px; left: 50px; width: 200px; height: 120px;
border:2px solid grey; z-index:9999; font-size:14px;
background-color:white;
">
<p style="margin:10px;">Legende</p>
<p style="background-color:orange; margin:5px;">Payant</p>
<p style="background-color:green; margin:5px;">Gratuit</p>
<p style="background-color:grey; margin:5px;">Information manquante</p>
<p style="background-color:cyan; margin:5px;">Carte ou badge</p>
<p style="background-color:yellow; margin:5px;">Charges gratuites de 12h à 14h et de 19h à 21h</p>
</div>
"""
# Ajoutez la légende personnalisée à la carte
map_osm.get_root().html.add_child(folium.Element(legend_html))
for index, lat, lon, com, acces_recharge in df[['ylatitude', 'xlongitude', 'n_station', 'acces_recharge']].itertuples():
# Créer un marqueur avec une couleur différente en fonction des valeurs
if acces_recharge == 'payant': fill_color = 'orange'
elif acces_recharge == 'gratuit': fill_color = 'green'
elif acces_recharge == 'information manquante': fill_color = 'grey'
elif acces_recharge == 'carte ou badge': fill_color = 'cyan'
elif acces_recharge == 'charges gratuites de 12 à 14h et de 19h à 21h': fill_color = 'yellow'
# Ajouter le marqueur à la carte
folium.RegularPolygonMarker(location=[lat, lon], popup=com, fill_color= fill_color, color =fill_color, radius=5).add_to(map_osm)
# Sauvegardez la carte au format HTML
#map_osm.save('/Users/augustincablant/Documents/GitHub/PyCar/DOWNLOAD/map_bornes.html')
map_osm